﻿namespace Zove.Runtime.Core.InferencingStrategy
{
    /// <summary>
    /// Basic inferencing strategy
    /// </summary>
    public class BasicInferencingStrategy : AbstractInferencingStrategy
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public BasicInferencingStrategy()
        {
            Name = "Basic Inferencing Strategy";
        }

        /// <summary>
        /// Run the algorithm
        /// </summary>
        /// <param name="zoveObject">the instance</param>
        public override void Infer(ZoveObject zoveObject)
        {
            bool updated = false;
            RuntimeFactor solved = null;
            RuntimeRule rr = null;

            do
            {
                foreach (RuntimeEquation re in zoveObject.Model.Equations)
                {
                    bool eligible = false;
                    foreach (RuntimeFactor e in re.Factors)
                    {
                        if (e.Status != RuntimeFactorStatus.Unknown)
                        {
                            continue;
                        }

                        rr = zoveObject.Model.GetRuntimeRule(re, e);
                        if (eligible == false && rr.Root != null)
                        {
                            solved = e;
                            eligible = true;
                        }
                        else
                        {
                            eligible = false;
                            break;
                        }
                    }
                    if (eligible)
                    {
                        updated = true;

                        solved.Solve(rr);

                        var se = new SolvedFactor();
                        se.Strategy = this;
                        se.Factor = solved;
                        se.Rule = rr;

                        //this.Evaluate(se);
                        zoveObject.Queue[solved.Name] = se;
                    }
                }
            } while (updated);
        }
    }
}